Completed
Push — master ( 0a8aee...45be8d )
by Andres
30s
created

angular.controller(ꞌct_redoxꞌ)   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 212

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
cc 1
c 4
b 0
f 1
nc 1
dl 0
loc 212
rs 8.2857
nop 6

14 Functions

Rating   Name   Duplication   Size   Complexity  
A ��) 0 4 1
A ��) 0 3 1
A ��) 0 5 1
D ��) 0 38 9
B ��) 0 21 7
A ��) 0 10 3
A ��) 0 7 1
A ��) 0 11 3
B ��) 0 27 5
A ��) 0 14 2
A ��) 0 12 3
A ��) 0 3 2
A ��) 0 23 3
A ��) 0 3 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/**
2
 redox
3
 Component that handles reduction/oxidation and ions.
4
5
 @namespace Components
6
 */
7
'use strict';
8
9
angular.module('game').component('redox', {
10
  templateUrl: 'views/redox.html',
11
  controller: 'ct_redox',
12
  controllerAs: 'ct'
13
});
14
15
angular.module('game').controller('ct_redox', ['state', 'data', 'visibility', 'util', 'format', 'reaction',
16
  function (state, data, visibility, util, format, reaction) {
17
    let ct = this;
18
    ct.state = state;
19
    ct.data = data;
20
    ct.util = util;
21
    ct.format = format;
22
    ct.reaction = reaction;
23
    ct.adjustAmount = [1, 10, 25, 100];
24
25
    ct.update = function(player) {
26
      processRedox(player);
27
      processElectronegativity(player);
28
    };
29
30
    function processRedox(player){
31
      for(let slot of player.element_slots){
32
        if(!slot){
33
          continue;
34
        }
35
        for (let redox of slot.redoxes) {
36
          if (!redox.resource || !redox.active || redox.from === redox.to) {
37
            continue;
38
          }
39
40
          let reactant = ct.generateName(redox.element, redox.from);
41
          let power = util.calculateValue(data.global_upgrades.redox_bandwidth.power.base,
42
                data.global_upgrades.redox_bandwidth.power,
43
                player.global_upgrades_current.redox_bandwidth);
44
          let number = Math.min(power, player.resources[reactant].number);
45
          let react = ct.redoxReaction(redox);
46
47
          ct.reaction.react(number, react, player);
48
        }
49
      }
50
    }
51
52
    function processElectronegativity(player){
53
      for(let key in data.elements){
54
        let element = data.elements[key];
55
        if(element.electronegativity === 0){
56
          continue;
57
        }
58
        let ions = element.anions.concat(element.cations);
59
		    ions.push(element.main);
60
        for(let resource of ions){
61
          if(player.resources[resource].number === 0){
62
            continue;
63
          }
64
          let charge = data.resources[resource].charge || 0;
65
          let probabilities = probabilityDistribution(key, charge);
66
          for(let probKey in probabilities){
67
            if(probKey === charge){
68
              continue;
69
            }
70
            let production = Math.floor(probabilities[probKey]*player.resources[resource].number);
71
            if(production === 0){
72
              continue;
73
            }
74
            let react = ct.redoxReaction({
75
              element: key,
76
              from: charge,
77
              to: parseInt(probKey, 10)
78
            });
79
            // electronegativity is 'for free'
80
      			react.reactant.eV = 0;
81
            // FIXME: starvation should fix this
82
            if(react.reactant['e-']){
83
              production = Math.min(production, player.resources['e-'].number);
84
            }
85
            ct.reaction.react(production, react, player);
86
          }
87
        }
88
      }
89
    }
90
91
    function probabilityDistribution(element, charge){
92
    	let prob = {};
93
    	let start = -data.elements[element].electron_affinity.length;
94
    	let end = charge;
95
    	// lower than index, affected by negativity
96
    	rangeProbability(element, prob, start, end, 1, data.elements[element].negative_factor);
97
98
    	prob[charge] = 1;
99
100
    	start = charge+1;
101
    	end = data.elements[element].ionization_energy.length+1;
102
    	// lower than index, affected by positivity
103
    	rangeProbability(element, prob, start, end, -1, data.elements[element].positive_factor);
104
105
    	let sum = 0;
106
    	for(let i in prob){
107
    		sum += prob[i];
108
    	}
109
    	for(let i in prob){
110
    		prob[i] /= sum;
111
    	}
112
    	return prob;
113
    }
114
115
    function rangeProbability(element, prob, start, end, offset, factor){
116
    	for(let i = start; i < end; i++){
117
    		let difference = data.redox[element][i]-data.redox[element][i+offset];
118
    		if(difference <= 0){
119
    			difference = -difference;
120
    		}else{
121
    			difference = 1/difference;
122
    		}
123
    		prob[i] = Math.pow(data.constants.ELECTRONEGATIVITY_CHANCE,Math.abs(i))*factor*difference;
124
    	}
125
    }
126
127
    /* Writes a redox in the form of a reaction so that we can use the reaction
128
    service to process it */
129
    ct.redoxReaction = function (redox) {
130
      let reactant = ct.generateName(redox.element, redox.from);
131
      let product = ct.generateName(redox.element, redox.to);
132
      let energy = redoxEnergy(redox.from, redox.to, redox.element);
133
134
      let react = {
135
        'reactant': {},
136
        'product': {}
137
      };
138
139
      react.reactant[reactant] = 1;
140
      react.product[product] = 1;
141
      if (energy > 0) {
142
        react.reactant.eV = energy;
143
      } else if (energy < 0) {
144
        react.product.eV = -energy;
145
      }
146
147
      let electron = redox.from - redox.to;
148
      if (electron > 0) {
149
        react.reactant['e-'] = electron;
150
      } else if (electron < 0) {
151
        react.product['e-'] = -electron;
152
      }
153
154
      return react;
155
    };
156
157
    /* Calculates how much energy it takes to go from a redox level to another
158
    for a given element */
159
    function redoxEnergy(from, to, element) {
160
      let energyFrom = data.redox[element][from];
161
      let energyTo = data.redox[element][to];
162
      let energy = energyTo - energyFrom;
163
164
      return energy;
165
    }
166
167
    /* Generates the name of a ion, e.g. O3+ */
168
    ct.generateName = function (element, i) {
169
      if (i === 0) {
170
        return data.elements[element].main;
171
      }
172
      let postfix = '';
173
      if (Math.abs(i) > 1) {
174
        postfix = Math.abs(i);
175
      }
176
      postfix += getSign(i);
177
      let name = element + postfix;
178
      return name;
179
    };
180
181
    function getSign(number) {
182
      return number > 0 ? '+' : '-';
183
    }
184
185
    ct.redoxSize = function (player) {
186
      let size = 0;
187
      for(let slot of player.element_slots){
188
        if(!slot){
189
          continue;
190
        }
191
        size += slot.redoxes.length;
192
      }
193
      return size;
194
    };
195
196
    /* Adds a new redox to the player list */
197
    ct.addRedox = function (player, slot) {
198
      if(ct.redoxSize(player) >= util.calculateValue(data.global_upgrades.redox_slots.power.base,
199
            data.global_upgrades.redox_slots.power,
200
            player.global_upgrades.redox_slots)){
201
        return;
202
      }
203
      slot.redoxes.push({
204
        resource: data.elements[slot.element].main,
205
        active: false,
206
        element: slot.element,
207
        from: 0,
208
        to: 1
209
      });
210
    };
211
212
    ct.removeRedox = function (slot, index) {
213
      slot.redoxes.splice(index, 1);
214
    };
215
216
    ct.visibleRedox = function(slot) {
217
      return slot.redoxes;
218
    };
219
220
    ct.adjustLevel = function(player, upgrade, amount){
221
      player.global_upgrades_current[upgrade] += amount;
222
      // We cap it between 1 and the current max level
223
      player.global_upgrades_current[upgrade] = Math.max(1, Math.min(player.global_upgrades_current[upgrade], player.global_upgrades[upgrade]));
224
    };
225
226
    state.registerUpdate('redox', ct.update);
227
  }
228
]);
229